home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 30
/
Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso
/
Aminet
/
dev
/
cross
/
GBDK-2.0.lha
/
GBDK
/
lib
/
realloc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-10-01
|
2KB
|
86 lines
#include <sys/malloc.h>
#include <stdlib.h>
#include <types.h>
#include <string.h>
void *realloc( void *current, UWORD size )
{
/* First see if the following hunk is free */
UWORD nextSize;
pmmalloc_hunk thisHunk, newHunk, ptr;
void *newRegion;
thisHunk = malloc_first;
ptr = (void *)((UWORD)current - sizeof(mmalloc_hunk));
if (size==0) {
free(current);
return NULL;
}
if (current==NULL) {
return malloc(size);
}
while (thisHunk && (thisHunk->magic==MALLOC_MAGIC)) {
if (thisHunk == ptr) {
debug("realloc", "Found hunk");
if (thisHunk->size == size )
return current;
if (thisHunk->size > size ) {
if (thisHunk->size > size + sizeof( mmalloc_hunk )) {
/* Shrink the hunk */
newHunk = (pmmalloc_hunk)(size + sizeof( mmalloc_hunk )+(UWORD)thisHunk);
newHunk->status = MALLOC_FREE;
newHunk->size = thisHunk->size - size -sizeof( mmalloc_hunk );
newHunk->magic = MALLOC_MAGIC;
newHunk->next = thisHunk->next;
thisHunk->next = newHunk;
thisHunk->size = size;
return current;
}
else {
/* Cant shrink the hunk as there's not enough room to put a new hunk header */
return current;
}
}
if (thisHunk->next != NULL) {
if (thisHunk->next->status == MALLOC_FREE) {
/* Stand a much better change if we gc first */
malloc_gc();
nextSize = thisHunk->next->size;
if ((nextSize + thisHunk->size + sizeof( mmalloc_hunk )) >= size ) {
/* Next hunk + this is big enough to contain the new hunk */
newHunk = (pmmalloc_hunk)(size + sizeof( mmalloc_hunk )+(UWORD)thisHunk);
newHunk->next = thisHunk->next->next;
newHunk->status = MALLOC_FREE;
newHunk->size = thisHunk->size + nextSize - size -sizeof( mmalloc_hunk );
newHunk->magic = MALLOC_MAGIC;
thisHunk->next = newHunk;
thisHunk->size = size;
return current;
}
}
/* Oh well. Allocate a new hunk then free this one */
newRegion = malloc (size);
if (newRegion) {
memcpy( newRegion, current, thisHunk->size );
free( current );
return newRegion;
}
return NULL; /* Couldnt do it */
}
}
thisHunk = thisHunk->next;
};
debug("realloc", "No hunk found");
return NULL;
}